import gradio as gr
import pandas as pd
import numpy as np
import time
from ultralytics import YOLO
import os
import subprocess
import uuid
from shutil import copy
import cv2

#重新定义UPLOAD_PATH和DETECT_PATH
UPLOAD_PATH = os.path.join(os.path.dirname(__file__),
'static/upload')
DETECT_PATH = os.path.join(os.path.dirname(__file__),
'static/result')
os.makedirs(UPLOAD_PATH, exist_ok=True)
os.makedirs(DETECT_PATH, exist_ok=True)

#生成UUID的函数
def generate_uuid():
    return str(uuid.uuid4())
#文件拷贝命令
def file_copy(src,dest):
    copy(src, dest)

def get_video_filename(video_path):
    return os.path.basename(video_path)
#加载模型
model = YOLO('yolov8n.pt')

#检测图片中的车牌以及该车牌的归属地
def process_image(img):
    # 先生成一个UUID
    uuid_path = generate_uuid()
    # 使用os.makedirs递归地创建目录
    os.makedirs(UPLOAD_PATH + "/" + uuid_path)
    os.makedirs(DETECT_PATH + "/" + uuid_path)
    filename = 'uploaded_image.jpg'
    file_path = os.path.join(UPLOAD_PATH + "/" + uuid_path,
filename)
    # 把图片复制到对应的UUID目录里面去。
    #img_filename = get_filename(img)
    #file_copy(img, os.path.join(UPLOAD_PATH + "/" +uuid_path,img_filename))
    #cv2.imwrite(file_path, img)
    # 将 RGB 转换为 BGR
    image_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
    cv2.imwrite(file_path, image_bgr)

    predict_command = [
        'python',
        'detect_plate.py',
        '--detect_model',
        'weights/plate_detect.pt',
        '--rec_model',
        'weights/plate_rec_color.pth',
        '--image_path',
        UPLOAD_PATH + "/" + uuid_path,
        '--output',
        'static/result/' + uuid_path
    ]

    try:
        subprocess.run(predict_command,
                       shell=True, timeout=1200)  # 超时时间是20分钟
        # 获取要返回的检测后的图片路径
        dected_img = 'static/result/' + uuid_path +'/uploaded_image.jpg'
        # dected_img = 'static/upload/' + uuid_path +'/uploaded_image.jpg'
        # 返回视频路径即可
        return dected_img
    except subprocess.CalledProcessError as e:
        return e.stderr


def process_video(video):
    # 假设处理这些输入并返回结果
    # 先生成一个UUID
    uuid_path = generate_uuid()
    # 使用os.makedirs递归地创建目录
    os.makedirs(UPLOAD_PATH + "/" + uuid_path)
    os.makedirs(DETECT_PATH + "/" + uuid_path)
    # 如果是视频则保存上传的视频
    print(get_video_filename(video))
    video_filename = get_video_filename(video)
    file_copy(video, os.path.join(UPLOAD_PATH + "/" +uuid_path, video_filename))

    # 要执行的yolo命令
    predict_command = [
        'python',
        'detect_plate.py',
        '--detect_model',
        'weights/plate_detect.pt',
        '--rec_model',
        'weights/plate_rec_color.pth',
        '--video',
        'static/upload/' + uuid_path + '/' + video_filename,
        # 是不是上传成功的视频文件地址
        '--output',
        'static/result/' + uuid_path
    ]
    try:
        subprocess.run(predict_command, timeout=1200)  # 超时时间是20分钟
        result_video_path = os.path.join('', 'result.mp4')
        dest_video_path = os.path.join('static/result/' +uuid_path, video_filename)
        file_copy(result_video_path, dest_video_path)
        # 获取要返回的视频文件路径
        video = 'static/result/' + uuid_path + '/' +video_filename
        # 返回视频路径即可
        return video
    except subprocess.CalledProcessError as e:
        return e.stderr


#感觉和前端的form是一回事。
iface_img = gr.Interface(
    fn=process_image,
    inputs=[gr.Image(label="上传图片")],
    outputs=[gr.Image(label="检测后的图片")],
    title="基于 YOLOv8的车牌检测系统",
    description="上传图像进行车牌检测"
)
iface_video = gr.Interface(
    fn=process_video,
    inputs=[gr.Video(label="上传视频")],
    outputs=[gr.Video(label="检测后的视频")],
    title="基于 YOLOv8的车牌检测系统",
    description="上传图像/视频并使用YOLOv8模型进行车牌检测"
)

# 主界面按钮
tabled_interface=gr.TabbedInterface([iface_img,iface_video],["车牌图像识别","车牌视频识别"])
#定义端口号
gradio_port = 8080
gradio_url = f"http://127.0.0.1:{gradio_port}"
tabled_interface.launch(
    server_name="127.0.0.1",
    server_port=gradio_port,
    debug=True,
    auth=("admin", "123456"),
    auth_message="请输入账号信息访问此应用。测试账号：admin,密码：123456",
    inbrowser=False,
    prevent_thread_lock=True,
    share=True
)